
`include "common_header.verilog"

//  *************************************************************************
//  File : p8264_sd_ln_top.v
//  *************************************************************************
//  This program is controlled by a written license agreement.
//  Unauthorized reproduction or use is expressly prohibited.
//  Copyright (c) 2010 MorethanIP
//  Muenchner Strasse 199, 85757 Karlsfeld, Germany
//  info@morethanip.com
//  http://www.morethanip.com
//  *************************************************************************
//  Designed by : Denis Poverennyy
//  info@morethanip.com
//  *************************************************************************
//  Description : The Serdes Lane Top is a set of individual Serdes Lane Blocks
//  for 12 lanes 
//  Version     : $Id: p8264_sd_ln_top.v,v 1.4 2014/10/09 14:58:07 dk Exp $
//  *************************************************************************

module p8264_sd_ln_top (

        reset_sd_rx_clk,
        sd_rx_clk,
        sd_rx_clk_ena,
        sd0_rx_66,
        sd1_rx_66,
        sd2_rx_66,
        sd3_rx_66,
        signal_det,
        sw_reset,
        disable_mld,
        block_lock,
        pcs_block_0,
        pcs_block_1,
        pcs_block_2,
        pcs_block_3,
        pcs_block_vl,
        vl_0_enc_vec,   
        vl_1_enc_vec,   
        vl_2_enc_vec,   
        vl_3_enc_vec  

`ifdef MTIPPCS_FEC_ENA
        ,
        fec_ena,
   `ifdef MTIPPCS82_EEE_ENA
        fec_fastlock,
   `endif
   `ifdef MTIPPCS_FECERR_ENA
        fec_err_ena,
   `endif
        fec_locked,
        fec_cerr,
        fec_ncerr
`endif   
`ifdef MTIPPCS82_EEE_ENA
        ,
        rx_mode_quiet,
        ram_period
`endif 

   );

input   [3:0]                   reset_sd_rx_clk;//  async active high reset
input   [3:0]                   sd_rx_clk;      //  Serdes clock
input   [3:0]                   sd_rx_clk_ena;  //  serdes clock enable
input   [66 - 1:0]              sd0_rx_66;      //  66-bit SERDES data Lane 0
input   [66 - 1:0]              sd1_rx_66;      //  66-bit SERDES data Lane 1 
input   [66 - 1:0]              sd2_rx_66;      //  66-bit SERDES data Lane 2 
input   [66 - 1:0]              sd3_rx_66;      //  66-bit SERDES data Lane 3 
input   [3:0]                   signal_det;     //  if low SERDES' signals are not valid
input   [3:0]                   sw_reset;       //  on sw reset search for a new Alignment Marker starts
input   [3:0]                   disable_mld;    //  disable MLD (10G/25G mode setting)
                                                //  When 16bit it uses bits 16:0;
input   [24*4-1:0]              vl_0_enc_vec;   //  Marker pattern for PCS Virtual Lane 0
input   [24*4-1:0]              vl_1_enc_vec;   //  Marker pattern for PCS Virtual Lane 1
input   [24*4-1:0]              vl_2_enc_vec;   //  Marker pattern for PCS Virtual Lane 2
input   [24*4-1:0]              vl_3_enc_vec;   //  Marker pattern for PCS Virtual Lane 3


output  [66:0]                  pcs_block_0;    //  66 Bit Block with sync header (2 lsb)
output  [66:0]                  pcs_block_1;    //  66 Bit Block with sync header (2 lsb)
output  [66:0]                  pcs_block_2;    //  66 Bit Block with sync header (2 lsb)
output  [66:0]                  pcs_block_3;    //  66 Bit Block with sync header (2 lsb)
output  [3:0]                   pcs_block_vl;   //  a write enable into the deskew buffer
output  [3:0]                   block_lock;     //  block per serdes lane

`ifdef MTIPPCS_FEC_ENA
input   [3:0]                   fec_ena; 
`ifdef MTIPPCS82_EEE_ENA
input   [3:0]                   fec_fastlock;   //  if set, allows fast FEC lock acquisition procedure. The signal set when
`endif                          //  LPI SM in the RX_WAKE state

`ifdef MTIPPCS_FECERR_ENA
input   [3:0]                   fec_err_ena;
`endif 
output  [3:0]                   fec_locked; 
output  [3:0]                   fec_cerr; 
output  [3:0]                   fec_ncerr;
`endif

`ifdef MTIPPCS82_EEE_ENA
input   [3:0]                   rx_mode_quiet;  // Indication that the remote has disabled its transmitter
input   [3:0]                   ram_period;     // if set the RAM is expected;
`endif


wire    [66:0]                  pcs_block_0; 
wire    [66:0]                  pcs_block_1; 
wire    [66:0]                  pcs_block_2; 
wire    [66:0]                  pcs_block_3; 
wire    [67*4 -1:0]             pcs_block;


`ifdef MTIPPCS_FEC_ENA
wire    [3:0]                   fec_locked; 
wire    [3:0]                   fec_cerr; 
wire    [3:0]                   fec_ncerr;
`endif

wire    [3:0]                   pcs_block_vl; 
wire    [3:0]                   block_lock;

// local

wire    [66*4-1:0]              sd_rx_vec;              //  concatenated 4 lanes
wire    [3:0]                   sw_reset_int;           //  sw reset to each lane
wire    [3:0]                   disable_mld_int;        //  disable MLD (10G/25G mode setting)


assign sd_rx_vec = {sd3_rx_66, sd2_rx_66, sd1_rx_66, sd0_rx_66};

assign {pcs_block_3,pcs_block_2,pcs_block_1,pcs_block_0} = pcs_block;

// when MLD bypass is active, only lane 0 stays active. Force reset to all others.

assign disable_mld_int = {3'b 000, disable_mld[0]};
assign sw_reset_int[0] = sw_reset[0];
assign sw_reset_int[1] = sw_reset[1] | disable_mld[1];
assign sw_reset_int[2] = sw_reset[2] | disable_mld[2];
assign sw_reset_int[3] = sw_reset[3] | disable_mld[3];

 

genvar gi;
generate for(gi=0; gi < 4; gi=gi+1)
begin:GL

sd_ln_blk_40g_64b U_SD_LN_BLK (
        .reset_sd_rx_clk        (reset_sd_rx_clk[gi]),
        .sd_rx_clk              (sd_rx_clk[gi]),
        .sd_rx_clk_ena          (sd_rx_clk_ena[gi]),
        .sd_rx                  (sd_rx_vec[66 * gi + 66 - 1:66 * gi]),
        .signal_det             (signal_det[gi]),
`ifdef MTIPPCS_FEC_ENA
        .fec_ena                (fec_ena[gi]),
        `ifdef MTIPPCS82_EEE_ENA
        .fec_fastlock           (fec_fastlock[gi]),
        `endif
        `ifdef MTIPPCS_FECERR_ENA
        .fec_err_ena            (fec_err_ena[gi]),
        `endif
        .fec_locked             (fec_locked[gi]),
        .fec_cerr               (fec_cerr[gi]),
        .fec_ncerr              (fec_ncerr[gi]),
`endif
`ifdef MTIPPCS82_EEE_ENA
        .rx_mode_quiet          (rx_mode_quiet[gi]),
        .ram_period             (ram_period[gi]),
`endif
        .sw_reset               (sw_reset_int[gi]),
        .disable_mld            (disable_mld_int[gi]),
        .vl_0_enc               (vl_0_enc_vec[24 * gi + 24 - 1:24 * gi]),
        .vl_1_enc               (vl_1_enc_vec[24 * gi + 24 - 1:24 * gi]),
        .vl_2_enc               (vl_2_enc_vec[24 * gi + 24 - 1:24 * gi]),        
        .vl_3_enc               (vl_3_enc_vec[24 * gi + 24 - 1:24 * gi]),                
        .block_lock             (block_lock[gi]),
        .pcs_block              (pcs_block[67 * gi + 67 - 1:67 * gi]),
        .pcs_block_vl           (pcs_block_vl[gi]));


end
endgenerate



endmodule // module p8264_sd_ln_top